<template>
  <el-upload
      ref="uploadRef"
      v-model:file-list="modelFileList"
      :action="action"
      :auto-upload="true"
      :before-upload="handleBeforeUpload"
      :data="fromData"
      :headers=Headers
      :http-request="submitUpload"
      :limit="limit"
      :on-change="uploadFileChange"
      :on-exceed="handleFileExceed"
      :on-remove="remove"
      :show-file-list=true
      class="upload-demo">
    <template #trigger>
      <el-button type="primary">选择文件</el-button>
    </template>
    <template #tip>
      <div v-if="props.isShowTip" class="el-upload__tip text-red">
        请上传大小不超过 <b style="color: #f56c6c">{{ props.fileSize }}MB</b>
        格式为 <b style="color: #f56c6c">{{
          props.fileType.join("/")
        }}</b><span v-if="props.fileType == 'mp4'" style="color: #f56c6c">(h264)</span>
        的文件
      </div>
    </template>
  </el-upload>
</template>

<script name="FileUpload" setup>
import {getToken} from "@/utils/auth";
import {ElMessage, genFileId} from 'element-plus';
import {ref} from "vue";
import {computed, nextTick, onMounted, watch} from "@vue/runtime-core";
// import { defineExpose } from 'vue';
import request from '@/utils/request'

const emits = defineEmits();
const {proxy} = getCurrentInstance();
const Headers = computed(() => {
  return {
    Authorization: 'Bearer ' + getToken()
  }
})
const modelFileList = ref([])
const {fileList} = ref([])
const fromData = ref({})
const file = ref({})

const props = defineProps({
  // 数量限制
  limit: {
    type: Number,
    default: 5,
  },
  // 大小限制(MB)
  fileSize: {
    type: Number,
    default: 100,
  },
  // 文件类型, 例如['png', 'jpg', 'jpeg']
  fileType: {
    type: Array,
    default: () => ["doc", "dox", "xls", "xlsx", "ppt", "pptx", "pdf", "mp4"],
  },
  // 是否显示提示
  isShowTip: {
    type: Boolean,
    default: true
  },
  action: {
    type: String,
    default: "/common/upload"
  },
  fileList: {
    type: Array,
    default: []
  }
});

const uploadRef = ref('');

const handleFileExceed = (files) => {
  uploadRef.value.clearFiles();
  const file = files[files.length - 1]
  file.uid = genFileId()
  uploadRef.value.handleStart(file)
}

// 上传前校检格式和大小
function handleBeforeUpload(file) {
  // 校检文件类型
  if (props.fileType.length) {
    let fileExtension = "";
    if (file.name.lastIndexOf(".") > -1) {
      fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
    }
    const isTypeOk = props.fileType.some((type) => {
      if (file.type.indexOf(type) > -1) return true;
      if (fileExtension && fileExtension.indexOf(type) > -1) return true;
      return false;
    });
    if (!isTypeOk) {
      proxy.$modal.msgError(`文件格式不正确, 请上传${props.fileType.join("/")}格式文件!`);
      return false;
    }
  }
  // 校检文件大小
  if (props.fileSize) {
    const isLt = file.size / 1024 / 1024 < props.fileSize;
    if (!isLt) {
      proxy.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
      return false;
    }
  }
  if (file.name.length - file.name.split('.').pop().length > 100) {
    ElMessage.error("上传的文件名最长100个字符");
    return false
  }
  return true;
}

function remove() {
  file.value = {}
}

const submitUpload = (data, callback) => {
  if (modelFileList.value) {
    if (modelFileList.value[0].size > 1048576000) {
      ElMessage.error("上传的文件不能超过1G");
      //catchback();
      return false
    }
  }
  const formData = new FormData();
  formData.append("file", modelFileList.value[0].raw);
  Object.keys(data)
      .filter((key) => data[key] !== null && data[key] !== undefined)
      .forEach((key) => {
        formData.append(key, data[key])
      });
  return request({
    url: props.action,
    method: 'POST',
    data: formData,
    headers: {
      'Content-Type': 'multipart/form-data'
    },
  }).then(response => {
    file.value = response;
    callback(response);
  }).catch(() => {
    //catchback();
  });
}

const clearFile = (data, callback) => {
  uploadRef.value.clearFiles();
}

defineExpose({submitUpload, clearFile})

function uploadFileChange(uploadFile, uploadfiles) {

}

//监听上传文件文件列表的数据变化
watch(
    () => file.value,
    () => {
      emits("getFileList", file.value);
    }
), {immediate: true};

//在onMounted中初始化编辑器
onMounted(() => {
  nextTick(() => {
    modelFileList.value = fileList.value
  })
});
</script>

<style scoped>

</style>
